home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / Messaging / OSL / OSLGSExm.c < prev    next >
Encoding:
Text File  |  1997-02-13  |  7.3 KB  |  270 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        OSLGSExm.c (Orignal name: OSLGetSetExmn.c)
  3.  
  4.     Contains:    OSL Globals
  5.  
  6.     Owned by:    Nick Pilch
  7.  
  8.     Copyright:    © 1992 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <3>      12/13/96    JP        1607652: Added & disabled debugging code
  13.          <7>     6/27/95    NP        1262792: Fix stack dynamic allocation
  14.                                     problem
  15.          <6>     6/24/95    TJ        Changed kNumStaticContextStackEntries from
  16.                                     a const to a #define so it would compile
  17.                                     with SC.
  18.          <5>     6/23/95    NP        1195474: Make Resolve reentrant.
  19.          <4>     2/22/95    eeh        1222904: fix use of SetCurrentContext
  20.          <3>      2/8/95    NP        1218550: Don't allocate OSLContexts
  21.                                     dynamically.
  22.          <2>     8/19/94    NP        1181622: Ownership fix.
  23.          <6>      5/5/94    eeh        bug #1160654: fix for SCPP
  24.          <5>      5/2/94    eeh        bug #1160654: various PPC native changes
  25.          <4>     8/18/93    NP        Added get and set current context.
  26.          <3>     7/29/93    NP        Removed compiler warning for unused
  27.                                     parameters.
  28.          <2>     7/28/93    NP        Mods for new token type, OSLToken.
  29.          <1>     7/21/93    NP        first checked in
  30.  
  31.     To Do:
  32. */
  33.  
  34. // ASSUMPTION: This code will be used in a library that has per-context globals!
  35.  
  36. #include "OSLPriv.h"
  37.  
  38.  
  39. #define kExmnKey1 'eone'
  40. #define kExmnKey2 'etwo'
  41.  
  42. #define    UNUSED(x) ((void) &x)
  43.  
  44. // set to 0 for no debugging & 1 for debugging
  45. #define LOGGING 0
  46. //debugging stuff
  47. // Declare somPrintf w/o having to include all those SOM headers:
  48. #if PRAGMA_IMPORT_SUPPORTED
  49. #pragma import on
  50. #endif
  51. int somPrintf (const char * fmt, ...);        // From <som.xh>
  52. #if PRAGMA_IMPORT_SUPPORTED
  53. #pragma import off
  54. #endif
  55. //
  56. #define LOG        if(!LOGGING) ; else somPrintf
  57.  
  58. // this guy should go away, and be replaced by calls to GetAccessor or 
  59. // GetEventHandler using the keys defined above.  This should allow a
  60. // more general storage mechanism if it becomes necessary.
  61. // static AEDesc theGlobal ;
  62.  
  63. OSLToken    theGlobalToken;
  64.  
  65. static OSErr
  66. GetGlobalDesc( unsigned long key1, unsigned long key2, AEDesc* desc )
  67. {
  68. //    return iAEGetObjectAccessor( key1, key2, (accessorProcPtr *)&desc->descriptorType,
  69. //            (long *)&desc->dataHandle, false, 0) ;
  70. //    *desc = theGlobalDesc;
  71.     UNUSED( key1 );
  72.     UNUSED( key2 );
  73.     UNUSED( desc );
  74.     return noErr;
  75. }
  76.  
  77. static OSErr
  78. SetGlobalDesc( unsigned long key1, unsigned long key2, AEDesc* desc )
  79. {
  80. //    return iAEInstallObjectAccessor( key1, key2, (accessorProcPtr)desc->descriptorType,
  81. //            (long)desc->dataHandle, false, 0) ;
  82. //    theGlobalDesc = *desc;
  83.     UNUSED( key1 );
  84.     UNUSED( key2 );
  85.     UNUSED( desc );
  86.     return noErr;
  87. }
  88.  
  89.  
  90. // Get the currently available "global" exmn token
  91. OSErr
  92. GetExmn( OSLToken *result )
  93. {
  94.     *result = theGlobalToken;
  95.     return noErr;
  96. //    return GetGlobalDesc( kExmnKey1, kExmnKey2, result ) ;
  97. }
  98.  
  99. // Set the "global" exmn token to this one
  100. OSErr
  101. SetExmn( OSLToken *newDesc )
  102. {
  103.     theGlobalToken = *newDesc;
  104.     return noErr;
  105. //    return SetGlobalDesc( kExmnKey1, kExmnKey2, newDesc ) ;
  106. }
  107.  
  108.  
  109. // Replace the currently available "global" exmn token with
  110. // the one provided here.  And return the old value in its
  111. // place.
  112. OSErr
  113. SwapExmn( AEDesc *oldAndNewDesc )
  114. {
  115.     AEDesc temp ;
  116.     OSErr err = GetGlobalDesc( kExmnKey1, kExmnKey2, &temp ) ;
  117.     if ( err == noErr )
  118.     {
  119.         err = SetGlobalDesc( kExmnKey1, kExmnKey2, oldAndNewDesc ) ;
  120.         if ( err == noErr )
  121.             *oldAndNewDesc = temp ;
  122.     }
  123.     return err ;
  124. }
  125.  
  126. //==============================================================================
  127. // Context stack
  128. //
  129. //    Maintain stack of current contexts, one for each time OSLResolve is called.
  130. //==============================================================================
  131.  
  132. #define    kNumStaticContextStackEntries 5
  133.  
  134. struct ContextStack
  135. {
  136.     unsigned short    numEntries;
  137.     OSLContext            contextArray[kNumStaticContextStackEntries];
  138.     unsigned short    bufferSize;
  139.     OSLContext*            buffer;
  140. };
  141. typedef struct ContextStack ContextStack;
  142.  
  143. ContextStack    gContextStack =
  144.     {false, {{NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}}, 0, NULL};
  145.  
  146. //------------------------------------------------------------------------------
  147. // AddContextToTopOfStack
  148. //
  149. //    Use static entries in structure until they are filled up and then do
  150. //    dynamic allocation. We don't ever shrink the dynamic structure, we only
  151. //    grow it.
  152. //------------------------------------------------------------------------------
  153.  
  154. OSErr AddContextToTopOfStack(OSLContext* context)
  155. {
  156.     OSErr    error = noErr;
  157.  
  158. #if LOGGING
  159.     // WE ALWAYS HAVE AT LEAST ONE THAT'S PUT ON THE STACK BY iAEObjectInit
  160.     if (gContextStack.numEntries == 2)
  161.         DebugStr("\pSomeone is actually calling Resolve reentrantly!");
  162. #endif
  163.  
  164.     LOG("=>Pushing OSL context: %8.8x\n", context->refCon);
  165.     if (gContextStack.numEntries < kNumStaticContextStackEntries)
  166.         gContextStack.contextArray[gContextStack.numEntries] = *context;
  167.     else
  168.     {
  169.         // THE FIRST TIME WE ARE CALLED TO ALLOCATE ONE MORE CONTEXT THAN
  170.         //    kNumStaticContextStackEntries
  171.         if (gContextStack.buffer == NULL)
  172.         {
  173.             gContextStack.buffer = (OSLContext*)NewPtr(sizeof(OSLContext));
  174.             if (error == noErr)
  175.             {
  176.                 if (gContextStack.buffer == NULL)
  177.                     error = memFullErr;
  178.             }
  179.             if (error == noErr)
  180.                 gContextStack.bufferSize = sizeof(OSLContext);
  181.         }
  182.         else
  183.         {
  184.             Size  newBufferSize =
  185.                     (gContextStack.numEntries - kNumStaticContextStackEntries
  186.                         + 1) * sizeof(OSLContext);
  187.             if (gContextStack.bufferSize < newBufferSize)
  188.             {
  189.                 OSLContext*    newBuffer = (OSLContext*)NewPtr(newBufferSize);
  190.                 error = MemError();
  191.                 if (error == noErr)
  192.                 {
  193.                     BlockMoveData(gContextStack.buffer, newBuffer,
  194.                                     gContextStack.bufferSize);
  195.                     DisposePtr((Ptr)gContextStack.buffer);
  196.                     gContextStack.buffer = newBuffer;
  197.                     gContextStack.bufferSize = newBufferSize;
  198.                 }
  199.             }
  200.         }
  201.         if (error == noErr)
  202.             *(gContextStack.buffer
  203.                 + (gContextStack.numEntries - kNumStaticContextStackEntries)) = *context;
  204.     }
  205.  
  206.     if (error == noErr)
  207.         ++gContextStack.numEntries;
  208.  
  209.     return error;
  210. }
  211.  
  212. //------------------------------------------------------------------------------
  213. // RemoveTopOfContextStack
  214. //------------------------------------------------------------------------------
  215.  
  216. OSErr RemoveTopOfContextStack()
  217. {
  218.     LOG("=>Popping OSL context\n");
  219.     --gContextStack.numEntries;
  220. #if LOGGING
  221.     {
  222.         // dump the new current context to the log file
  223.         OSLContext context;
  224.         GetCurrentContext(&context);
  225.     }
  226. #endif
  227.     return noErr;
  228. }
  229.  
  230. //OSLContext    theGlobalContext;
  231.  
  232. //------------------------------------------------------------------------------
  233. // GetCurrentContext
  234. //------------------------------------------------------------------------------
  235.  
  236. OSErr GetCurrentContext( OSLContext* curContext )
  237. {
  238. //    *curContext = theGlobalContext;
  239.     if (gContextStack.numEntries <= kNumStaticContextStackEntries)
  240.         *curContext = gContextStack.contextArray[gContextStack.numEntries - 1];
  241.     else
  242.     {
  243.         *curContext =
  244.             *(gContextStack.buffer
  245.             + (gContextStack.numEntries - kNumStaticContextStackEntries - 1));
  246.     }
  247.     LOG("Getting OSL context: %8.8x\n", curContext->refCon);
  248.     return noErr;
  249. }
  250.  
  251. //------------------------------------------------------------------------------
  252. // SetCurrentContext
  253. //------------------------------------------------------------------------------
  254.  
  255. OSErr SetCurrentContext( OSLContext* curContext )
  256. {
  257. //    theGlobalContext = *curContext;
  258.     LOG("+Setting OSL context: %8.8x\n", curContext->refCon);
  259.     if (gContextStack.numEntries <= kNumStaticContextStackEntries)
  260.         gContextStack.contextArray[gContextStack.numEntries - 1] = *curContext;
  261.     else
  262.     {
  263.         *(gContextStack.buffer
  264.             + (gContextStack.numEntries - kNumStaticContextStackEntries - 1))
  265.                     = *curContext;
  266.     }
  267.     return noErr;
  268. }
  269.  
  270.